package cn.edu.buaa.cnsatm.traffic_big_data_server.highway.service;

import cn.edu.buaa.cnsatm.traffic_big_data_server.aviation.service.AirportService;
import cn.edu.buaa.cnsatm.traffic_big_data_server.highway.dao.HighwayCongestionDAO;
import cn.edu.buaa.cnsatm.traffic_big_data_server.highway.dao.HighwayStatusDAO;
import cn.edu.buaa.cnsatm.traffic_big_data_server.highway.dao.ImageDAO;
import cn.edu.buaa.cnsatm.traffic_big_data_server.integrated.model.RoadStatusModel;
import cn.edu.buaa.cnsatm.traffic_big_data_server.integrated.dao.RoadStatusDAO;
import cn.edu.buaa.cnsatm.traffic_big_data_server.util.DateUtil;
import cn.edu.buaa.cnsatm.traffic_big_data_server.util.JDBCUtil;
import cn.edu.buaa.cnsatm.traffic_big_data_server.util.PropertiesUtil;
import cn.edu.buaa.cnsatm.traffic_big_data_server.util.WebSpiderUtil;
import cn.edu.buaa.cnsatm.traffic_big_data_server.waterway.service.SeaStatusService;
import cn.edu.buaa.cnsatm.traffic_big_data_server.waterway.service.TyphoonService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.*;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.postgresql.util.PSQLException;

import javax.naming.directory.SearchResult;
import javax.print.DocFlavor;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class HighwayTSService {
    public static String getTopKHighwayWeatherEffect(int k) throws SQLException {
        /**
         * @author: LX
         * @methodName: getTopKHighwayWeatherEffect
         * @description: 从数据库中获取前k条公路气象
         * @data:
         **/
        ResultSet resultSet = HighwayStatusDAO.getTopKHighwayWeatherEffect(k);
        JsonArray ja = new JsonArray();
        while (resultSet.next()){
            JsonObject jo = new JsonObject();
            jo.addProperty("info",resultSet.getString("block_description"));
            jo.addProperty("type", resultSet.getString("block_reason"));
            jo.addProperty("title", resultSet.getString("block_title"));
            String datetime = resultSet.getString("block_start_time");
            jo.addProperty("datetime",datetime.substring(0, datetime.length() - 3));
            ja.add(jo);
        }
        resultSet.getStatement().close();
        resultSet.close();
        return ja.toString();
    }
    public static String getHighWayTSFromWebSaveToDatabase() throws InterruptedException, ParseException, IOException, SQLException {
        /**
         * @author: LX
         * @methodName: getHighWayWeatherImageFromWeb
         * @description: 从http://www.mot.gov.cn爬取公路天气图，按照配置文件中的地址存储
         * @data:
         **/
        String highwayTSSQLString = new String("-- 公路气象影响\n");
        final String HIGHWAY_WEATHER_IMAGE_URL_LEFT = "http://www.nmc.cn/publish/traffic.html";
            Document document = WebSpiderUtil.getHTMLDocument(HIGHWAY_WEATHER_IMAGE_URL_LEFT);
            //System.out.println(document.toString());
            String dateString = "";
            Elements dateElements = document.getElementsByClass("author").get(0).getElementsByTag("b");
            dateString = dateElements.get(0).text() + "-" + dateElements.get(1).text() + "-" + dateElements.get(2).text();
            System.out.println(dateString);
            Elements highWayWeatherURL = document.getElementsByClass("writing");
            Elements effectWeatherText = highWayWeatherURL.get(0).getElementsByTag("p");
            boolean isEffectBegin = false;
            String currentEffect = "无";
            for(Element elementP: effectWeatherText){
                if(elementP.text().length() < 4) continue;//长度过段
                    //if(currentEffect.contains("、")) continue;
                if(elementP.text().contains("的主要路段有")) {
                    currentEffect = elementP.text().substring(0, elementP.text().length() - 7);
                    continue;
                }
                if(currentEffect == "无") continue;
                String effectRoad = elementP.text();//受影响的路段，如：青兰高速(G22)甘肃定西—榆中—兰州段
                System.out.println(effectRoad);
                //System.out.println(effectRoad);
                RoadStatusModel roadStatusModel = new RoadStatusModel(
                            "公路", "气象", effectRoad + currentEffect, null,
                            dateString, null, null,
                            dateString);
                int posGaoSuOrGuoDao = effectRoad.lastIndexOf("高速");
                if(posGaoSuOrGuoDao == -1){posGaoSuOrGuoDao = effectRoad.lastIndexOf("国道");}
                roadStatusModel.setBlock_title(effectRoad.substring(0, posGaoSuOrGuoDao + 2) + currentEffect);
                highwayTSSQLString = highwayTSSQLString + RoadStatusDAO.insertRoadStatus(roadStatusModel, false) + "\n";
                }

        return highwayTSSQLString;
    }
    public static void main(String args[]) throws InterruptedException, ParseException, IOException, SQLException {
        //System.out.println(getHighwayAccidentFromWebSaveToDatabase());
        //System.out.println(getWeatherAlarmFromWebAndSaveToDatabase());
//        boolean yes = true;
//        while(yes){
//            try{
//                JDBCUtil.startConnection();
//                yes = false;
//            } catch (PSQLException e){
//                continue;
//            }
//        }
//        System.out.println("-- 公路气象");
//        System.out.println(getHighWayTSFromWebSaveToDatabase());
        System.out.println("-- 公路事故"+getHighwayAccidentFromWebSaveToDatabase());
        getHighwayAccidentFromWebSaveToDatabase();
//        System.out.println("-- 铁路、水路气象");
//        getWeatherAlarmFromWebAndSaveToDatabase();
//        //TyphoonService.getTyphoonFromWebAndSaveToDatabase();
//        System.out.println("-- 海况");
//        SeaStatusService.getAllSeaStatusSaveToDataBase();
//        System.out.println("-- 禁航");
//        SeaStatusService.getSeaBlockFromWebAndSaveToDatabase();
//        String typhoon1 = "INSERT into road_status (road_type, block_reason, block_description, block_geom, block_start_time, block_end_time_plan, block_end_time_real, update_time, block_reason) " +
//                "values(" + "'水路'" + ", " + "'气象'" + ", "  +
//                "'受台风娜基莉影响，南海区域禁航'" + ", " + null + ", " +
//                "'2019-11-09 08:00:00'" + ", " + null+ ", " +
//                null + ", " + "'2019-11-09 08:00:00'" +  "," + "'台风导致南海禁航'" + ");";
//        System.out.println("-- 公路事件");
//        getHighwayBlockFromWebSaveToDatabase();
//        System.out.println("-- 公路拥挤度");
//        HighwayCongestionService.getHighwayCongestionFromWebSaveToDatabase();
//        System.out.println("-- 航空气象");
//        AirportService.getAllAirportWeatherFromWebSaveToDatabase();
    }
    public static String getHighwayBlockFromWebSaveToDatabase() throws InterruptedException, SQLException {
        /**
         * @author: LX
         * @methodName: getHighwayBlockFromWebSaveToDatabase
         * @description: 爬取公路阻断信息
         * @data:
         **/
        String highwayBlockSQLString = new String("-- 公路事件阻断\n");
        boolean yes = true;
        String HIGHWAY_BLOCK_URL = "http://www.chinahighway.org.cn/chinahighway/";
        String BLOCK_JSON_URL_LEFT = "http://www.chinahighway.org.cn/chinahighway/blockById.do?type=json&id=";
        Document document = null;
        Elements blockList = null;//获取阻断事件URL列表
        while(yes){
            try{
                document = WebSpiderUtil.getHTMLDocument(HIGHWAY_BLOCK_URL);
                blockList = document.select("a[block_id]");
                yes = false;
            }catch (Exception e){
                continue;
            }
        }
        boolean isJump = true;
        for(Element block: blockList){//遍历每个阻断事件，获取其ID，拼接为请求的jsonURL
            isJump = !isJump;
            if (isJump) continue;//不加这句会重复

            String blockID = block.attr("block_id");
            String blockJsonString = WebSpiderUtil.getJsonFromURL(BLOCK_JSON_URL_LEFT + blockID);
            //读取公路阻断JSON，装入数据库
            JSONObject blockJsonObject = JSON.parseObject(blockJsonString);
            RoadStatusModel roadStatusModel = new RoadStatusModel(
                    "公路", "事件", blockJsonObject.getString("scene_desc"), null,
                    blockJsonObject.getString("detect_time"), null, null,
                    blockJsonObject.getString("update_time"));
            roadStatusModel.setBlock_title(blockJsonObject.getString("road_name") + blockJsonObject.getString("stop_reason"));
            highwayBlockSQLString = highwayBlockSQLString + RoadStatusDAO.insertRoadStatus(roadStatusModel, false) + "\n";
            //TODO:去掉事件描述开头的事件，需要写正则
        }
        return highwayBlockSQLString;
    }
    public static String getHighwayAccidentFromWebSaveToDatabase() throws InterruptedException, SQLException {
        /**
         * @author: LX
         * @methodName: getHighwayAccidentFromWebSaveToDatabase
         * @description: 爬取高速公路事故信息
         * @data:
         **/
        String highwayAccidentSQLString = new String("-- 公路事故\n");
//        final String[] STOP_WORD = {"恢复","正常","结束","解除","关注","下载","处理完毕", "通行正常"};
//        final String[] EVENT_WORD = {"封闭","关闭","阻断","管制","中断","无法下道","断交","维修","施工"};
//        final String[] ACCIDENT_WORD = {"撞车","抛锚","追尾"};
//        final String[] IGNORE_WORD = {"【实时路况】","【全省路况报道】","首报：", "服务平台提示：","注意行车安全。祝您出行平安。 咨询电话：0797—8770100","请过往车辆按照交通标志秩序通行，因施工造成不便，敬请谅解。","详细情况请关注\"河北高速\"微信公众平台","\"河北高速通\"手机APP","河北省高速公路出行信息服务网",
//                "请司乘人员谨慎驾驶，注意行车安全。高速出行服务平台提供","【事故首发】","请过往车辆按照交通标志秩序通行，因施工造成不便，敬请谅解。","实时路况咨询，信息咨询，意见建议，投诉举报，救援服务请拨打青海省交通运输服务监督电话【12328】 ...",};
        //String HIGWWAY_ACCIDENT_URL = "https://www.icauto.com.cn/gonglu/index.html";
        String HIGHWAY_ACCIDENT_URL = "http://www.chinahighway.org.cn/chinahighway/blocksearch.do?nowpage=1&blockType=0&key=&dist=-1&road_id=&type=%2C14";
        //String HIGHWAY_LIST_URL = "https://www.icauto.com.cn/gonglu/gaosu_g/";
        //String HIGHWAY_LIST_URL = "http://gsgl.00cha.com/";
        //String shit = "road.asp";
        JSONArray ja = new JSONArray();
        while(true){
            try{
                String accidentJson = WebSpiderUtil.getJsonFromURL(HIGHWAY_ACCIDENT_URL);
                //System.out.println(accidentJson + "hi");
                JSONObject jo = JSON.parseObject(accidentJson);
                ja = jo.getJSONArray("listData");
            }catch (Exception e){
                continue;
            }
            break;
        }

        for(int i = 0; i < ja.size(); i++){
            JSONObject accident = ja.getJSONObject(i);
            String blockTitle = accident.getString("road_name") + "发生交通事故 " +  accident.getString("measures_name");
            if(!blockTitle.contains("高速")) continue;
            String updateTime = accident.getString("detect_time");
            String endTime = accident.getString("estimate_time");
            String blockDesc = accident.getString("scene_desc");
            RoadStatusModel roadStatusModel = new RoadStatusModel("公路", "事故", blockDesc, null,
                    updateTime, endTime, null, updateTime);
            //if(accidentArray[i].lastIndexOf("高速"))
            roadStatusModel.setBlock_title(blockTitle);
            //TODO:正则匹配高速
            highwayAccidentSQLString = highwayAccidentSQLString + RoadStatusDAO.insertRoadStatus(roadStatusModel, false) + "\n";

        }
        return highwayAccidentSQLString;
    }
    public static String getWeatherAlarmFromWebAndSaveToDatabase() throws IOException, InterruptedException, SQLException {
        /**
         * @author: LX
         * @methodName: getHighwayAccidentFromWebSaveToDatabase
         * @description: 爬取高恶劣天气，在此我认为大风红、大风橙、沙尘暴红会影响铁路，大雾红会影响船，大风红会影响船
         * @data:
         **/
        final String[] RAIL_EFFECT_WEATHER = {"大风红", "大风橙", "沙尘暴红"};
        final String[] RAIL_KEY_WORD = {"列车", "铁路", "动车", "高铁", "火车"};
        final String[] BOAT_EFFECT_WEATHER = {"大雾红", "大风红", "大风橙", "台风"};
        final String[] BOAT_KEY_WORD = {"港口", "海区", "海域", "船", "禁航"};

        String weatherAlarmSQLString = new String("-- 气象警报 导致铁路水路停运\n");
        final String WEATHER_ALARM_URL = "http://www.12379.cn/data/alarm_list_all.html";//更新频率可以为两天，建议一天
//        Document d = WebSpiderUtil.getHTMLDocument("http://www.12379.cn/data/alarm_list_all.html");
//        String documentString = d.toString();
//        String[] cnm = documentString.split("\n");
        JSONArray weatherArray = new JSONArray();
        while (true){
            try{
                String weatherAlarmJsonString = WebSpiderUtil.getJsonFromURL(WEATHER_ALARM_URL, "Hm_lvt_e92165ac1511573056df3e0addc9e11d=1572777978");
                //System.out.println(WebSpiderUtil.getJsonFromURL(WEATHER_ALARM_URL, "Hm_lvt_e92165ac1511573056df3e0addc9e11d=1572777978"));
                JSONObject weatherAlarmJson = JSON.parseObject(weatherAlarmJsonString);
                weatherArray = weatherAlarmJson.getJSONArray("alertData");
            }catch (NullPointerException e){
                continue;
            }
            break;
        }

        /* 示例：
         {
		    "description": "黎川县气象局2019年11月03日21时04分发布大雾黄色预警信号：预计12小时内黎川县可能出现能见度小于500米的大雾，请注意交通安全。",
		    "headline": "黎川县气象局发布大雾黄色预警[III级/较重]",
		    "identifier": "36102241600000_20191103210407",
	    	"sendTime": "2019-11-03 21:04:07"
    	}
         */
        for(int i = 0; i < weatherArray.size(); i++){
            JSONObject jsonObject = weatherArray.getJSONObject(i);
            String weatherAlarm = jsonObject.getString("headline");
            String weatherAlarmDescription = jsonObject.getString("description");
            //System.out.println(weatherAlarmDescription);
            if(weatherAlarm.contains("解除")) continue;//不关心解除预警
            boolean[] isEffected = {false, false, false, false};
            String[] positionKeyWord ={"气象台", "气象局", "区", "县", "市", "旗", "省"};
            String blockPosition = "";
            for(String keyword: positionKeyWord){
                if(weatherAlarm.contains(keyword)){
                    if(keyword.length() == 3){
                        blockPosition = weatherAlarm.substring(0, weatherAlarm.lastIndexOf(keyword));
                    }
                    else{
                        blockPosition = weatherAlarm.substring(0, weatherAlarm.lastIndexOf(keyword) + 1);
                    }
                    break;
                }
            }
            for(String railEffect: RAIL_EFFECT_WEATHER) if(weatherAlarm.contains(railEffect)) {isEffected[0] = true; break;}
            for(String railEffect: RAIL_KEY_WORD) if(weatherAlarmDescription.contains(railEffect)) {isEffected[1] = true; break;}
            for(String boatEffect: BOAT_EFFECT_WEATHER) if(weatherAlarm.contains(boatEffect)) {isEffected[2] = true; break;}
            for(String railEffect: BOAT_KEY_WORD) if(weatherAlarmDescription.contains(railEffect)) {isEffected[3] = true; break;}
            if(isEffected[0] || isEffected[1]){
                RoadStatusModel roadStatusModel = new RoadStatusModel("铁路", "气象", weatherAlarm + ", 部分铁路停运", null,
                        jsonObject.getString("sendTime"), null, null, jsonObject.getString("sendTime"));
                //TODO:正则匹配地区名
                if(weatherAlarm.contains("大风")) roadStatusModel.setBlock_title(blockPosition + "部分铁路受大风影响");
                if(weatherAlarm.contains("沙尘暴")) roadStatusModel.setBlock_title(blockPosition + "部分铁路受沙尘暴影响");
                weatherAlarmSQLString = weatherAlarmSQLString + RoadStatusDAO.insertRoadStatus(roadStatusModel, false) + "\n";
            }
            if(isEffected[2] && isEffected[3]){
                RoadStatusModel roadStatusModel = new RoadStatusModel("水路", "气象", weatherAlarm + "，附近海域禁航", null,
                        jsonObject.getString("sendTime"), null, null, jsonObject.getString("sendTime"));
                if(weatherAlarm.contains("大风")) roadStatusModel.setBlock_title(blockPosition + "部分海域受大风影响");
                if(weatherAlarm.contains("大雾")) roadStatusModel.setBlock_title(blockPosition + "部分海域受大雾影响");
                if(weatherAlarm.contains("台风")) roadStatusModel.setBlock_title(blockPosition + "部分海域受台风影响");
                weatherAlarmSQLString = weatherAlarmSQLString + RoadStatusDAO.insertRoadStatus(roadStatusModel, false) + "\n";
            }
        }
        return weatherAlarmSQLString;
    }
}
